package top.bug.blog.service.impl;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import top.bug.blog.service.LikeService;
import top.bug.blog.utils.StrUtils;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;

/**
 * @author <a href="https://github.com/jiusi66">九思.</a>
 * @email 10837907@qq.com
 * @from <a href="https://www.52bug.top">递归茶馆-www.52bug.top</a>
 * @description 点赞操作 实现类
 */
@Service
@Slf4j
public class LikeServiceImpl implements LikeService {
    /**
     * 点赞记录缓存
     */
    private final Cache<String, Boolean> likeCache = Caffeine.newBuilder()
            // 根据内存情况调整
            .maximumSize(30_000)
            .expireAfterWrite(24, TimeUnit.HOURS)
            .build();

    @Override
    public boolean tryLike(String keyPrefix, String ip, String contentId) {
        if (StrUtils.isAnyBlank(keyPrefix, ip, contentId)) {
            return false;
        }
        String cacheKey = buildCacheKey(ip, contentId, keyPrefix);
        // 判断缓存中是否存在
        Boolean exists = likeCache.getIfPresent(cacheKey);
        if (exists != null && exists) {
            // 已经点过赞
            return false;
        }
        // 没点过赞 -> 写入缓存
        likeCache.put(cacheKey, true);
        return true;
    }

    @Override
    public boolean cancelLike(String keyPrefix, String ip, String contentId) {
        if (StrUtils.isAnyBlank(keyPrefix, ip, contentId)) {
            return false;
        }
        String cacheKey = buildCacheKey(ip, contentId, keyPrefix);
        Boolean exists = likeCache.getIfPresent(cacheKey);
        if (exists == null) {
            // 未点赞，无法取消
            return false;
        }
        // 移除缓存
        likeCache.invalidate(cacheKey);
        return true;
    }

    @Override
    public boolean hasLikedToday(String keyPrefix, String ip, String contentId) {
        if (StrUtils.isAnyBlank(keyPrefix, ip, contentId)) {
            return false;
        }
        String cacheKey = buildCacheKey(ip, contentId, keyPrefix);
        return likeCache.getIfPresent(cacheKey) != null;
    }

    private String buildCacheKey(String ip, String contentId, String prefix) {
        String format = String.format("%s:%s:%s",
                // 处理IPv6地址
                ip.replace(":", "_"),
                contentId,
                LocalDate.now().format(DateTimeFormatter.ISO_DATE)
        );
        return prefix + format;
    }
}
